﻿using System;
using System.ServiceProcess;
using System.Threading;
using System.Threading.Tasks;
using CommandLine;
using SuiHan.Commons.Logging;
using SuiHan.Commons.WindowsService;
using SuiHan.ProcessDaemon.WinService;

namespace SuiHan.ProcessDaemon {
    internal class Program {
        public static void Main(string[] args) {
            if (args.Length == 0) {
                RunCommandShell();
                return;
            }

            Parser.Default.ParseArguments<RunOptions>(args).WithParsed(RunApplication);
        }

        private static Logger _logger;

        private static Logger logger {
            get {
                _logger ??= LoggerFactory.GetCurrentLogger();
                return _logger;
            }
        }

        private static void RunApplication(RunOptions options) {
            AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException;
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

            ServiceBase[] services = { new DaemonService(options) };
            ServiceBase.Run(services);
        }

        private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) {
            logger.Error($"[TaskScheduler]未处理的异常: {sender} {e?.Exception}");
        }

        private static void AppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
            logger.Error($"[AppDomain]未处理的异常: {sender} {e.ExceptionObject}");
            if (e.ExceptionObject is Exception exception) {
                logger.Error(exception.StackTrace);
            }
        }

        private static void RunCommandShell() {
            const string serviceName = "DaemonService";
            ServiceInstaller installer = new() {
                ServiceName = serviceName,
                DisplayName = serviceName,
                Description = "守护进程",
                StartType = ServiceStartMode.Automatic
            };

            start:
            Console.WriteLine("请选择你要执行的操作： （1）安装服务，（2）卸载服务，（3）查看服务状态，（Q）退出。");
            ConsoleKey key = Console.ReadKey().Key;
            Console.WriteLine();

            switch (key) {
                case ConsoleKey.NumPad1 or ConsoleKey.D1: {
                    ServiceController service = ServiceHelper.GetService(serviceName);
                    if (service != null) {
                        Console.WriteLine("服务已经安装");
                        goto start;
                    }

                    Console.WriteLine("正在安装服务");
                    ServiceHelper.ConfigService(installer, true);

                    Console.WriteLine("正在启动服务");
                    ServiceHelper.StartService(serviceName);
                    goto start;
                }

                case ConsoleKey.NumPad2 or ConsoleKey.D2: {
                    ServiceController service = ServiceHelper.GetService(serviceName);
                    if (service != null) {
                        Console.WriteLine("正在卸载服务");
                        ServiceHelper.ConfigService(installer, false);
                    } else {
                        Console.WriteLine("服务未安装");
                    }

                    goto start;
                }

                case ConsoleKey.NumPad3 or ConsoleKey.D3: {
                    ServiceController service = ServiceHelper.GetService(serviceName);
                    if (service != null) {
                        Console.WriteLine(service.Status);
                    } else {
                        Console.WriteLine("服务未安装");
                    }

                    goto start;
                }
                case ConsoleKey.Q:
                    Environment.Exit(0);
                    return;
            }

            Console.WriteLine("无效按键");
            goto start;
        }
    }
}
